Skip to content

v3.0 dev#623

Draft
tobixen wants to merge 21 commits intomasterfrom
v3.0-dev
Draft

v3.0 dev#623
tobixen wants to merge 21 commits intomasterfrom
v3.0-dev

Conversation

@tobixen
Copy link
Member

@tobixen tobixen commented Feb 8, 2026

Lots of minor commits, most of them trying to get all the integration tests to pass

Doc fixing, CHANGELOG updates and a workaround for some test problems.
@tobixen tobixen force-pushed the v3.0-dev branch 2 times, most recently from f2637c7 to 68809dc Compare February 9, 2026 01:28
tobixen and others added 11 commits February 13, 2026 09:31
- Raise minimum Python version to 3.10+ in pyproject.toml
- Add ruff linter/formatter configuration, pytest-asyncio and httpx
  test dependencies
- Add async-niquests and sync-requests CI test matrix jobs
- Add lychee link-check workflow and .lycheeignore
- Update pre-commit hooks configuration
- Rename AI_POLICY.md to AI-POLICY.md for consistency
- Add test server config YAML to .gitignore

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduce a layered architecture separating protocol logic from I/O:

- Protocol layer (caldav/protocol/): Pure functions for XML building
  and parsing with typed request/response dataclasses (DAVRequest,
  DAVResponse, PropfindResult, CalendarQueryResult)
- Operations layer (caldav/operations/): Sans-I/O business logic for
  CalDAV operations -- properties, search, calendar management,
  calendar objects, principal discovery
- Response layer (caldav/response.py): BaseDAVResponse with shared
  XML response parsing for sync and async clients
- Data state (caldav/datastate.py): Strategy pattern for managing
  calendar data representations (raw string, icalendar, vobject)

This enables code reuse between sync and async implementations and
improves testability through pure function isolation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add AsyncDAVClient with httpx (preferred) and niquests async fallback
- Extract BaseDAVClient ABC with shared auth, config, and URL logic
- Extract auth utilities to caldav/lib/auth.py (WWW-Authenticate
  parsing, auth scheme selection)
- Add caldav/aio.py as async entry point with backward-compat
  Async* aliases (AsyncCalendar, AsyncEvent, etc.)
- Refactor DAVClient to inherit from BaseDAVClient, reducing
  duplication between sync and async code paths
- Replace eager imports in caldav/__init__.py with PEP 562 lazy
  loading for faster startup (heavy deps deferred until first use)
- Remove caldav/objects.py backward-compatibility shim

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Make Calendar, Principal, Event, Todo, Journal work transparently
  with both DAVClient (sync) and AsyncDAVClient (async)
- Add get_* method aliases for server-fetching operations
  (get_calendars, get_events, get_todos, get_display_name, etc.)
- Deprecate date_search() in favor of search(), DAVObject.name in
  favor of get_display_name()
- Refactor search.py to generator-based Sans-I/O pattern --
  _search_impl yields (SearchAction, data) tuples consumed by
  sync or async wrappers
- Add CalendarObjectResource.id property returning UID
- Integrate DataState for efficient data representation management
- Add edit_icalendar_instance() and edit_vobject_instance() context
  managers for safe mutable access to calendar data

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add get_connection_params() for unified config discovery from
  multiple sources (explicit params, env vars, config files)
- Add resolve_features() for feature profile resolution with
  base+override support in YAML config
- Raise errors on config file parse failures (breaking change)
- Add feature configuration validation
- Extend compatibility hints for Zimbra, Bedework, CCS, Davis,
  DAViCal, GMX, ecloud, Synology, SOGo, Posteo, PurelyMail,
  Xandikos, Baikal, and Radicale
- Fix _derive_from_subfeatures partial-config derivation bugs
- Add URL space validation in lib/url.py
- Fall back to principal URL when calendar-home-set is missing
- Minor code quality improvements in elements/ and lib/ modules
  (Python 3.10+ syntax, import cleanup, ruff formatting)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace legacy tests/conf.py with new tests/test_servers/ framework:

- Add TestServer base class hierarchy (Embedded, Docker, External)
- Add YAML-based server configuration (caldav_test_servers.yaml)
- Add ServerRegistry for server discovery and lifecycle management
- Add client_context() and has_test_servers() helpers
- Add Docker test infrastructure for CCS (Apple CalendarServer),
  DAViCal, Davis, and Zimbra
- Update existing Baikal, Cyrus, Nextcloud, SOGo Docker configs
- Add convert_conf_private.py migration tool for old config format
- Add fixture_helpers.py with shared test fixtures
- Remove deprecated tests/conf.py, conf_baikal.py, conf_private.py

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
New test suites:
- test_protocol.py: Unit tests for Sans-I/O protocol layer
  (XML building/parsing with typed dataclasses)
- test_operations_*.py (6 files): Unit tests for operations layer
  (properties, search, calendar, calendarobject, calendarset, principal)
- test_async_davclient.py: AsyncDAVClient unit tests
- test_async_integration.py: Async integration tests with test servers
- test_lazy_import.py: PEP 562 lazy import verification

Updated existing tests:
- test_caldav.py: Modernize integration tests for new test framework
- test_caldav_unit.py: Expand unit test coverage
- test_compatibility_hints.py: Add feature derivation tests
- Other test files: Import cleanup and ruff formatting

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add comprehensive v3.0 code review (docs/design/V3_CODE_REVIEW.md)
- Add design documents for Sans-I/O architecture, API analysis,
  data representation, method generation, and implementation plans
- Add code review notes for niquests and urllib3-future dependencies
- Add async usage documentation (docs/source/async.rst)
- Add HTTP library configuration docs (docs/source/http-libraries.rst)
- Update tutorial, howtos, and about pages for v3.0
- Add async usage examples and get_calendars example
- Update all examples to use get_davclient() factory
- Expand CHANGELOG.md with comprehensive v3.0.0a1 entry covering
  lazy imports, context managers, feature profiles, compatibility
  hints, new test infrastructure, and all bug fixes
- Update README.md with async support highlights

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Zimbra does not support substring text matching - it accepts the
REPORT with text-match match-type="contains" but only does exact
matching. Searching for "Bastille Day" returns 0 results while
"Bastille Day Party" (exact summary) returns 1.

With this hint, the library correctly expects 0 results from
implicit substring searches and uses client-side filtering for
explicit substring searches.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Zimbra:
- Remove save-load.get-by-url unsupported hint (works in zcs-foss:latest,
  was broken in older Zimbra versions)
- Remove event_by_url_is_broken old flag (same reason)
- Add save.duplicate-uid.cross-calendar unsupported (Zimbra treats
  same-UID events across calendars as aliases of the same event)

Cyrus:
- Add save.duplicate-uid.cross-calendar unsupported (enforces unique
  UIDs across all calendars for a user)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cyrus Docker container does not enforce password authentication,
accepting any password. Use the sentinel value that the test suite
already recognizes to skip the wrong-password test.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@tobixen tobixen marked this pull request as ready for review February 13, 2026 13:16
@tobixen tobixen marked this pull request as draft February 13, 2026 13:17
tobixen and others added 6 commits February 13, 2026 14:19
Master contains squashed versions of earlier v3.0-dev work; v3.0-dev
has the latest rebased history with all fixes. Conflicts resolved by
keeping v3.0-dev content.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

# Conflicts:
#	caldav/objects.py
Replace conf_private.py references in Docker test server READMEs,
about.rst, test_caldav.py header, and RELEASE-HOWTO.md with the
new caldav_test_servers.yaml config format and TEST_<SERVER> env vars.

Also exclude caldav_test_servers.yaml and tmp_caldav_test_servers.yaml
from MANIFEST.in to prevent test configs from being included in PyPI
releases.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…may have been a false negative due to their caching issue
compatibility_hints.py:
- Posteo: add search.time-range.todo.old-dates unsupported (recent dates
  work, old dates don't), add search.text.substring unknown
- Purelymail: mark flapping features as fragile (search.is-not-defined
  was full now ungraceful, search.time-range.event was unsupported now
  ungraceful, search.time-range.todo was ungraceful now unsupported),
  add search.text.substring unknown

search_ops.py:
- Catch ValueError from icalendar_searcher.check_component() when
  server returns data with invalid recurrence structure (e.g. after
  compatibility hacks strip DURATION). Include the object unfiltered
  rather than crashing. Fixes jeanes testRecurringDateWithExceptionSearch.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
I realize that I've broken my own AI-policy mutliple times now on other projects, and I will continue spending 30s on asking Claude to submit bug-fixing pull requests when needed  - so I'm changing the AI-policy
tobixen and others added 2 commits February 14, 2026 11:55
Make fixture_helpers.py the single source of truth for the core
create-or-find-calendar logic. _fixCalendar_ now delegates to the
sync get_or_create_test_calendar, keeping only test-infrastructure
concerns (caching, cleanup regime, cal_id defaults).

- Add sync get_or_create_test_calendar with consolidated logic
- Rename async version to aget_or_create_test_calendar
- Extract shared helpers: _build_make_calendar_kwargs,
  _filter_calendars_by_component_set, _find_test_calendar
- Update test_async_integration.py imports

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant